home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-10-06 | 45.1 KB | 1,905 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // SpriteWorldUtils.c
- //
- // Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
- //
- // Description: some utilities for creating worlds of sprites
- ///--------------------------------------------------------------------------------------
-
- #ifndef __QUICKDRAW__
- #include <QuickDraw.h>
- #endif
-
- #ifndef __QDOFFSCREEN__
- #include <QDOffscreen.h>
- #endif
-
- #ifndef __WINDOWS__
- #include <Windows.h>
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __GESTALT__
- #include <Gestalt.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include <TextUtils.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __SWCOMMON__
- #include <SWCommonHeaders.h>
- #endif
-
- #ifndef __SPRITEWORLD__
- #include <SpriteWorld.h>
- #endif
-
- #ifndef __SPRITELAYER__
- #include <SpriteLayer.h>
- #endif
-
- #ifndef __SPRITE__
- #include <Sprite.h>
- #endif
-
- #ifndef __SPRITEFRAME__
- #include <SpriteFrame.h>
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include <SpriteWorldUtils.h>
- #endif
-
- #ifndef __BLITPIXIEINTERFACE__
- #include <BlitPixieInterface.h>
- #endif
-
- ///-------------------------------------------------------------------------------------
-
- #define kSolid 0x00000000UL // mask solid value (all zeros : "black" *)
- #define kClear 0xFFFFFFFFUL // mask clear value (all ones : "white" *)
-
- // * In Indexed Color (< 16-bit), the mask IMAGE is inversed (not the actual bits).
- // (since the first index is white and the last index is black in a Mac color table)
-
-
- #define kAlphaMask16 0x7FFF // masking value to remove the alpha channel (keep RGB)
- #define kAlphaMask32 0x00FFFFFFL
-
- ///-------------------------------------------------------------------------------------
-
- RGBColor gSWTransparentColor = // transparent pixel color
- {0xFFFF,0xFFFF,0xFFFF}; // default color: white
-
- static void ComputePixelValues( short pixelSize );
-
- static UInt16 SWMaskedRGBValue; // masked pixel R/G/B value (used by the ColorSearch procs)
- static UInt16 SWTransparentRGBValue; // transparent pixel R/G/B value (used by the ColorSearch procs)
-
- static OSErr gSWStickyError;
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateRegionFromCIconMask
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateRegionFromCIconMask(
- RgnHandle *maskRgn,
- CIconHandle cIconH)
- {
- OSErr err = noErr;
- RgnHandle tempMaskRgn;
- char saveState;
- BitMap iconMask;
-
- *maskRgn = NULL;
-
- saveState = HGetState((Handle)cIconH);
- HLock((Handle)cIconH);
-
- iconMask.rowBytes = (**cIconH).iconMask.rowBytes;
- iconMask.bounds = (**cIconH).iconMask.bounds;
- iconMask.baseAddr = (Ptr)(**cIconH).iconMaskData;
-
- tempMaskRgn = NewRgn();
-
- if (tempMaskRgn != NULL)
- {
- err = BitMapToRegion(tempMaskRgn, &iconMask);
-
- if (err == noErr)
- {
- *maskRgn = tempMaskRgn;
- }
- else
- {
- DisposeRgn(tempMaskRgn);
- }
- }
- else
- {
- err = MemError();
- }
-
- HSetState((Handle)cIconH, saveState);
-
- SWSetStickyIfError( err );
- return err;
- }
-
- /*
- ///--------------------------------------------------------------------------------------
- // SWCreateRegionFromPict
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateRegionFromPict(
- RgnHandle *pictRgnH,
- PicHandle srcPictH)
- {
- RgnHandle tempRgnH;
- GWorldPtr saveGWorld,
- offScrnGWld;
- GDHandle saveGDH;
- Rect frameRect;
- ColorSearchUPP blackenColSearchUPP;
- OSErr err;
-
- GetGWorld(&saveGWorld, &saveGDH );
-
- *pictRgnH = NULL;
- frameRect = (**srcPictH).picFrame;
- OffsetRect(&frameRect, -frameRect.left, -frameRect.top);
-
- err = NewGWorld( &offScrnGWld, 1, &frameRect, nil, nil, 0 );
-
- if (err == noErr)
- {
- blackenColSearchUPP = NewColorSearchProc( blackenColorSearch );
- (void)LockPixels( GetGWorldPixMap(offScrnGWld) );
- SetGWorld(offScrnGWld, nil);
- AddSearch( blackenColSearchUPP );
- EraseRect(&frameRect);
- DrawPicture(srcPictH, &frameRect);
- DelSearch( blackenColSearchUPP );
- DisposeRoutineDescriptor( blackenColSearchUPP );
- tempRgnH = NewRgn();
-
- if (tempRgnH != NULL && err == noErr)
- {
- err = BitMapToRegion(tempRgnH, (BitMap*)*GetGWorldPixMap( offScrnGWld ) );
-
- if (err == noErr)
- {
- *pictRgnH = tempRgnH;
- }
- else
- {
- DisposeRgn(tempRgnH);
- }
- }
- else
- {
- if ( err == noErr )
- err = MemError();
- }
-
- SetGWorld(saveGWorld, nil);
- DisposeGWorld(offScrnGWld);
- }
-
- SWSetStickyIfError( err );
- return err;
- }
- */
-
- ///--------------------------------------------------------------------------------------
- // SWCreateRegionFromGWorldAndRect - expects an already blackened maskGWorld.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateRegionFromGWorldAndRect(
- RgnHandle *maskRgn,
- GWorldPtr maskGWorld,
- Rect* frameRect)
- {
- OSErr err = noErr;
- GDHandle saveGDH;
- GWorldPtr saveGWorld,
- tempMaskGWorld;
- Rect tempMaskRect;
-
-
- *maskRgn = NULL;
-
- GetGWorld(&saveGWorld, &saveGDH);
-
- tempMaskRect = *frameRect;
- OffsetRect(&tempMaskRect, -tempMaskRect.left, -tempMaskRect.top);
-
- err = SWCreateRegionFromGWorldAndRectStart( &tempMaskGWorld, tempMaskRect.right,
- tempMaskRect.bottom );
-
- if (err == noErr)
- {
- err = SWCreateRegionFromGWorldAndRectPartial( maskRgn, maskGWorld,
- tempMaskGWorld, frameRect );
-
- SWCreateRegionFromGWorldAndRectFinish( tempMaskGWorld );
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateRegionFromGWorldAndRectStart
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateRegionFromGWorldAndRectStart(
- GWorldPtr *tempMaskGWorld,
- short maxWidth,
- short maxHeight)
- {
- OSErr err = noErr;
- Rect tempMaskRect;
-
-
- SetRect( &tempMaskRect, 0, 0, maxWidth, maxHeight );
- err = NewGWorld( tempMaskGWorld, 1, &tempMaskRect, nil, nil, 0 );
- if (err == noErr)
- {
- (void)LockPixels( GetGWorldPixMap( *tempMaskGWorld ) );
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateRegionFromGWorldAndRectFinish
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCreateRegionFromGWorldAndRectFinish(
- GWorldPtr tempMaskGWorld)
- {
- if ( tempMaskGWorld != NULL )
- {
- DisposeGWorld(tempMaskGWorld);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateRegionFromGWorldAndRectPartial
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateRegionFromGWorldAndRectPartial(
- RgnHandle *maskRgn,
- GWorldPtr maskGWorld,
- GWorldPtr tempMaskGWorld,
- Rect* frameRect)
- {
- OSErr err = noErr;
- GDHandle saveGDH;
- GWorldPtr saveGWorld;
- Rect tempMaskRect;
- RgnHandle tempRgnH;
-
-
- *maskRgn = NULL;
-
- GetGWorld(&saveGWorld, &saveGDH);
-
- tempMaskRect = *frameRect;
- OffsetRect(&tempMaskRect, -tempMaskRect.left, -tempMaskRect.top);
-
- (void)LockPixels( GetGWorldPixMap(maskGWorld) );
- SetGWorld(tempMaskGWorld, nil);
-
- CopyBits(
- (BitMap*)*GetGWorldPixMap( maskGWorld ),
- (BitMap*)*GetGWorldPixMap( tempMaskGWorld ),
- frameRect,
- &tempMaskRect,
- srcCopy,
- nil );
-
- tempRgnH = NewRgn();
- if (tempRgnH != NULL)
- {
- err = BitMapToRegion(tempRgnH, (BitMap*)*GetGWorldPixMap( tempMaskGWorld ) );
-
- UnlockPixels( GetGWorldPixMap(maskGWorld) );
-
- if (err == noErr)
- {
- *maskRgn = tempRgnH;
- }
- else
- {
- DisposeRgn(tempRgnH);
- }
- }
- else
- {
- err = MemError();
- }
- SetGWorld(saveGWorld, nil);
-
- SWSetStickyIfError( err );
- return err;
- }
-
- #pragma mark -
-
- ///--------------------------------------------------------------------------------------
- // SWCreateGWorldFromPictResource
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateGWorldFromPictResource(
- SpriteWorldPtr destSpriteWorld,
- GWorldPtr *pictGWorldP,
- short pictResID)
- {
- OSErr err = noErr;
- PicHandle newPictH;
-
-
- newPictH = GetPicture(pictResID);
-
- if (newPictH != NULL)
- {
- err = SWCreateGWorldFromPict(destSpriteWorld, pictGWorldP, newPictH);
-
- ReleaseResource((Handle)newPictH);
- }
- else
- {
- err = ResError();
- if (err == noErr)
- {
- err = resNotFound;
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateGWorldFromPict
- // creates a offScreen GWorld and draws the specified pict into it
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateGWorldFromPict(
- SpriteWorldPtr destSpriteWorld,
- GWorldPtr *pictGWorld,
- PicHandle pictH)
- {
- OSErr err;
- GWorldPtr saveGWorld;
- GDHandle saveGDevice;
- GWorldPtr tempGWorld;
- Rect pictRect;
- short depth;
- GDHandle theGDH;
-
-
- *pictGWorld = NULL;
-
- GetGWorld(&saveGWorld, &saveGDevice);
-
- depth = destSpriteWorld->pixelDepth;
- theGDH = destSpriteWorld->mainSWGDH;
-
- pictRect = (**pictH).picFrame;
- OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
-
- if ( (**((**theGDH).gdPMap)).pixelSize == depth )
- err = NewGWorld( &tempGWorld, depth, &pictRect, nil, theGDH, noNewDevice );
- else
- err = NewGWorld( &tempGWorld, depth, &pictRect, nil, nil, 0 );
-
- if (err == noErr)
- {
- *pictGWorld = tempGWorld;
-
- SetGWorld(tempGWorld, nil);
-
- (void)LockPixels( GetGWorldPixMap(tempGWorld) );
- EraseRect(&pictRect);
- DrawPicture(pictH, &pictRect);
- UnlockPixels( GetGWorldPixMap(tempGWorld) );
- }
-
- SetGWorld(saveGWorld, saveGDevice);
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateGWorldFromCIconMask
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateGWorldFromCIconMask(
- SpriteWorldPtr destSpriteWorld,
- GWorldPtr *maskGWorldP,
- CIconHandle cIconH)
- {
- OSErr err;
- GWorldPtr saveGWorld;
- GDHandle saveGDevice;
- char saveState;
- BitMap maskBitMap;
- GWorldPtr tempGWorldP;
- short depth;
- GDHandle theGDH;
-
-
- GetGWorld(&saveGWorld, &saveGDevice);
-
- depth = destSpriteWorld->pixelDepth;
- theGDH = destSpriteWorld->mainSWGDH;
-
- saveState = HGetState((Handle)cIconH);
- HLock((Handle)cIconH);
-
- maskBitMap.rowBytes = (**cIconH).iconMask.rowBytes;
- maskBitMap.bounds = (**cIconH).iconMask.bounds;
- maskBitMap.baseAddr = (Ptr)(**cIconH).iconMaskData;
-
- if ( (**((**theGDH).gdPMap)).pixelSize == depth )
- err = NewGWorld( &tempGWorldP, depth, &maskBitMap.bounds, nil, theGDH, noNewDevice );
- else
- err = NewGWorld( &tempGWorldP, depth, &maskBitMap.bounds, nil, nil, 0 );
-
- if (err == noErr)
- {
- SetGWorld(tempGWorldP, NULL);
-
- (void)LockPixels( GetGWorldPixMap(tempGWorldP) );
- CopyBits(&maskBitMap,
- (BitMap*)*GetGWorldPixMap( tempGWorldP ),
- &maskBitMap.bounds,
- &maskBitMap.bounds,
- srcCopy,
- nil);
- UnlockPixels( GetGWorldPixMap(tempGWorldP) );
-
- *maskGWorldP = tempGWorldP;
- }
-
- SetGWorld(saveGWorld, saveGDevice);
-
- HSetState((Handle)cIconH, saveState);
-
- SWSetStickyIfError( err );
- return err;
- }
-
- #pragma mark -
-
- ///--------------------------------------------------------------------------------------
- // SWInvertGWorld - inverts a GWorld's image. This is used to invert B&W masks.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWInvertGWorld(
- GWorldPtr gWorldP)
- {
- SWInvertRect(gWorldP, &gWorldP->portRect);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWInvertRect - inverts a portion of a GWorld. Called by SWUpdateFrameMasks
- // and SWInvertGWorld.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWInvertRect(
- GWorldPtr gWorldP,
- RectPtr rectP)
- {
- PixMapHandle pixMapH;
- GWorldFlags pixelsState;
- GWorldPtr saveGWorld;
- GDHandle saveDevice;
-
- pixMapH = GetGWorldPixMap( gWorldP );
- pixelsState = GetPixelsState( pixMapH );
- (void)LockPixels( pixMapH );
-
- GetGWorld( &saveGWorld, &saveDevice);
- SetGWorld(gWorldP, (GDHandle) NULL);
-
- InvertRect(rectP);
-
- SetGWorld( saveGWorld, saveDevice);
- SetPixelsState( pixMapH, pixelsState );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCopyGWorlds - copies srcGWorldP into dstGWorldP.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCopyGWorlds( GWorldPtr srcGWorldP, GWorldPtr dstGWorldP )
- {
- PixMapHandle srcPixMapH;
- PixMapHandle dstPixMapH;
- GWorldFlags srcPixelsState;
- GWorldFlags dstPixelsState;
- GWorldPtr saveGWorld;
- GDHandle saveDevice;
-
- srcPixMapH = GetGWorldPixMap( srcGWorldP );
- dstPixMapH = GetGWorldPixMap( dstGWorldP );
-
- srcPixelsState = GetPixelsState( srcPixMapH );
- dstPixelsState = GetPixelsState( dstPixMapH );
- (void) LockPixels( srcPixMapH );
- (void) LockPixels( dstPixMapH );
-
- GetGWorld( &saveGWorld, &saveDevice);
- SetGWorld(dstGWorldP, (GDHandle) NULL);
-
- CopyBits( (BitMap*)*srcPixMapH, (BitMap*)*dstPixMapH,
- &srcGWorldP->portRect, &dstGWorldP->portRect, srcCopy, (RgnHandle) NULL );
-
- SetGWorld( saveGWorld, saveDevice);
-
- SetPixelsState( srcPixMapH, srcPixelsState );
- SetPixelsState( dstPixMapH, dstPixelsState );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFlipPixelsHorizontally - mirrors part of a gworld horizontally
- // Works in any depth, but is slow in depths below 8-bits.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWFlipPixelsHorizontally(GWorldPtr dstGWorldP, RectPtr rectP)
- {
- Ptr baseAddr,row;
- UInt32 rowBytes;
- Rect bounds;
- int width,height;
- int x,y,depth;
- GWorldFlags state;
- PixMapHandle pixMapHdl;
-
- pixMapHdl = GetGWorldPixMap( dstGWorldP );
-
- state = GetPixelsState(pixMapHdl);
- (void) LockPixels(pixMapHdl);
-
- depth = (**pixMapHdl).pixelSize;
- if ( rectP == NULL )
- bounds = (**pixMapHdl).bounds;
- else
- bounds = *rectP;
-
- width = bounds.right - bounds.left;
- height = bounds.bottom - bounds.top;
-
- START_32_BIT_MODE
-
- baseAddr = SWGetPixBaseAddr(pixMapHdl);
- rowBytes = SWGetPixRowBytes(pixMapHdl);
-
- baseAddr += bounds.top * rowBytes;
- baseAddr += (bounds.left * depth) >> 3;
-
- row = baseAddr;
-
- switch ( depth ) // bits per pixel
- {
- case 1:
- {
- Boolean pixel1,pixel2;
- int x2;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0, x2 = (width-1); x < (width >> 1); x++, x2-- )
- {
- pixel1 = BitTst(row,x);
- pixel2 = BitTst(row,x2);
-
- pixel1 ? BitSet(row,x2) : BitClr(row,x2);
- pixel2 ? BitSet(row,x ) : BitClr(row,x );
- }
- row += rowBytes;
- }
- break;
- }
- case 2:
- case 4:
- {
- RGBColor color1,color2;
- int x2;
- GWorldPtr saveGWorld;
- GDHandle saveGDevice;
-
- GetGWorld( &saveGWorld, &saveGDevice );
- SetGWorld( dstGWorldP, (GDHandle) NULL );
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0, x2 = (width-1); x < (width >> 1); x++, x2-- )
- {
- GetCPixel(x ,y, &color1);
- GetCPixel(x2,y, &color2);
-
- SetCPixel(x2,y, &color1);
- SetCPixel(x ,y, &color2);
- }
- }
-
- SetGWorld( saveGWorld, saveGDevice );
-
- break;
- }
- case 8:
- {
- UInt8 *ptr1,*ptr2,temp;
-
- for ( y = 0; y < height; y++ )
- {
- ptr1 = (UInt8 *) row;
- ptr2 = ptr1 + width;
- for ( x = 0; x < (width >> 1); x++ )
- {
- temp = *--ptr2;
- *ptr2 = *ptr1;
- *ptr1++ = temp;
- }
- row += rowBytes;
- }
- break;
- }
- case 16:
- {
- UInt16 *ptr1,*ptr2,temp;
-
- for ( y = 0; y < height; y++ )
- {
- ptr1 = (UInt16 *) row;
- ptr2 = ptr1 + width;
- for ( x = 0; x < (width >> 1); x++ )
- {
- temp = *--ptr2;
- *ptr2 = *ptr1;
- *ptr1++ = temp;
- }
- row += rowBytes;
- }
- break;
- }
- case 32:
- {
- UInt32 *ptr1,*ptr2,temp;
-
- for ( y = 0; y < height; y++ )
- {
- ptr1 = (UInt32 *) row;
- ptr2 = ptr1 + width;
- for ( x = 0; x < (width >> 1); x++ )
- {
- temp = *--ptr2;
- *ptr2 = *ptr1;
- *ptr1++ = temp;
- }
- row += rowBytes;
- }
- break;
- }
- default:
- // unknown pixel depth
- break;
- }
-
- END_32_BIT_MODE
-
- SetPixelsState(pixMapHdl,state);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFlipPixelsVertically - mirrors part of a gworld vertically
- // Works in any depth, but is slow in depths below 8-bits.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWFlipPixelsVertically(GWorldPtr dstGWorldP, RectPtr rectP)
- {
- Ptr baseAddr,row1,row2;
- UInt32 rowBytes;
- Rect bounds;
- int width,height;
- int x,y,depth;
- GWorldFlags state;
- PixMapHandle pixMapHdl;
-
- pixMapHdl = GetGWorldPixMap( dstGWorldP );
-
- state = GetPixelsState(pixMapHdl);
- (void) LockPixels(pixMapHdl);
-
- depth = (**pixMapHdl).pixelSize;
- if ( rectP == NULL )
- bounds = (**pixMapHdl).bounds;
- else
- bounds = *rectP;
-
- width = bounds.right - bounds.left;
- height = bounds.bottom - bounds.top;
-
- START_32_BIT_MODE
-
- baseAddr = SWGetPixBaseAddr(pixMapHdl);
- rowBytes = SWGetPixRowBytes(pixMapHdl);
-
- baseAddr += bounds.top * rowBytes;
- baseAddr += (bounds.left * depth) >> 3;
-
- row1 = baseAddr;
- row2 = baseAddr + (height-1) * rowBytes;
-
- switch ( depth ) // bits per pixel
- {
- case 1:
- {
- Boolean pixel1,pixel2;
-
- for ( y = 0; y < (height >> 1); y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- pixel1 = BitTst(row1,x);
- pixel2 = BitTst(row2,x);
-
- pixel1 ? BitSet(row2,x) : BitClr(row2,x);
- pixel2 ? BitSet(row1,x) : BitClr(row1,x);
- }
- row1 += rowBytes;
- row2 -= rowBytes;
- }
- break;
- }
- case 2:
- case 4:
- {
- RGBColor color1,color2;
- int y2;
- GWorldPtr saveGWorld;
- GDHandle saveGDevice;
-
- GetGWorld( &saveGWorld, &saveGDevice );
- SetGWorld( dstGWorldP, (GDHandle) NULL );
-
- for ( y = 0, y2 = (height-1); y < (height >> 1); y++, y2-- )
- {
- for ( x = 0; x < width; x++ )
- {
- GetCPixel(x,y , &color1);
- GetCPixel(x,y2, &color2);
-
- SetCPixel(x,y2, &color1);
- SetCPixel(x,y , &color2);
- }
- }
-
- SetGWorld( saveGWorld, saveGDevice );
-
- break;
- }
- case 8:
- {
- UInt8 *ptr1,*ptr2,temp;
-
- for ( y = 0; y < (height >> 1); y++ )
- {
- ptr1 = (UInt8 *) row1;
- ptr2 = (UInt8 *) row2;
- for ( x = 0; x < width; x++ )
- {
- temp = *ptr1;
- *ptr1++ = *ptr2;
- *ptr2++ = temp;
- }
- row1 += rowBytes;
- row2 -= rowBytes;
- }
- break;
- }
- case 16:
- {
- UInt16 *ptr1,*ptr2,temp;
-
- for ( y = 0; y < (height >> 1); y++ )
- {
- ptr1 = (UInt16 *) row1;
- ptr2 = (UInt16 *) row2;
- for ( x = 0; x < width; x++ )
- {
- temp = *ptr1;
- *ptr1++ = *ptr2;
- *ptr2++ = temp;
- }
- row1 += rowBytes;
- row2 -= rowBytes;
- }
- break;
- }
- case 32:
- {
- UInt32 *ptr1,*ptr2,temp;
-
- for ( y = 0; y < (height >> 1); y++ )
- {
- ptr1 = (UInt32 *) row1;
- ptr2 = (UInt32 *) row2;
- for ( x = 0; x < width; x++ )
- {
- temp = *ptr1;
- *ptr1++ = *ptr2;
- *ptr2++ = temp;
- }
- row1 += rowBytes;
- row2 -= rowBytes;
- }
- break;
- }
- default:
- // unknown pixel depth
- break;
- }
-
- END_32_BIT_MODE
-
- SetPixelsState(pixMapHdl,state);
- }
-
- #pragma mark -
-
- ///-------------------------------------------------------------------------------------
- // SWSetTransparentColor - allows you to set the background, or unmasked color
- // of a sprite to a color other than white. Important: the sprite's background color
- // MUST match the color you use with gSWTransparentColor, or the Sprite won't load correctly.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetTransparentColor(RGBColor *RGB)
- {
- gSWTransparentColor = *RGB;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // ComputePixelValues
- ///--------------------------------------------------------------------------------------
-
- void ComputePixelValues( short pixelSize )
- {
- if ( pixelSize <= 8 )
- {
- // Indexed Color
- SWMaskedRGBValue = 0x0000; // black, becomes last index : all ones
- SWTransparentRGBValue = 0xFFFF; // white, becomes first index : all zeros
- }
- else
- {
- // Direct Color
- SWMaskedRGBValue = 0xFFFF; // white, is RGB : all ones
- SWTransparentRGBValue = 0x0000; // black, is RGB : all zeros
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreatePixelMaskFromGWorld - converts the image in pictureGWorld to a black and white
- // mask that is stored in maskGWorld.
- // Portions having gSWTransparentColor will be cleared ("white"), others made solid ("black").
- // This function doubles as a faster version of SWBlackenGWorld.
- //
- // Note1: the maskGWorld will be completely redrawn, so it can contain garbage
- // Note2: this function handles unlocked GWorlds (locks them temporarily)
- // Note3: both GWorlds must be the same depth
- //
- // IMAGE -> MASK
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreatePixelMaskFromGWorld( GWorldPtr pictureGWorld, GWorldPtr maskGWorld, RectPtr rectP )
- {
- UInt32 transparent;
- GWorldPtr saveGWorld;
- GDHandle saveDevice;
- Ptr baseAddr;
- Ptr maskAddr;
- long rowBytes;
- long width,height;
- long depth;
- long x,y;
- unsigned short transparentValue;
- PixMapHandle pictPix;
- PixMapHandle maskPix;
- GWorldFlags pictPixelsState;
- GWorldFlags maskPixelsState;
- OSErr err = noErr;
-
- pictPix = GetGWorldPixMap( pictureGWorld );
- maskPix = GetGWorldPixMap( maskGWorld );
-
- SW_ASSERT( (**pictPix).pixelSize == (**maskPix).pixelSize );
-
- if ( rectP == NULL )
- rectP = &pictureGWorld->portRect;
-
- width = rectP->right - rectP->left;
- height = rectP->bottom - rectP->top;
-
- depth = (**pictPix).pixelSize;
- ComputePixelValues(depth);
- transparentValue = SWTransparentRGBValue;
-
- // Determine whether we need to fix the image's GWorld too,
- // at the same time as creating the mask.
- if (gSWTransparentColor.red != transparentValue ||
- gSWTransparentColor.green != transparentValue ||
- gSWTransparentColor.blue != transparentValue )
- {
- return SWCreateMaskAndFixImage(pictureGWorld, maskGWorld, rectP);
- }
-
- // This function won't work in depths lower than 8-bit, so we
- // need to call the old SWBlackenGWorld in this case.
- if (depth < 8)
- {
- SWCopyGWorlds(pictureGWorld, maskGWorld);
- SWBlackenGWorld(maskGWorld);
- if (depth <= 8 )
- SWInvertGWorld(maskGWorld);
-
- return noErr;
- }
-
- GetGWorld( &saveGWorld, &saveDevice);
-
- pictPixelsState = GetPixelsState( pictPix );
- LockPixels( pictPix );
- maskPixelsState = GetPixelsState( maskPix );
- LockPixels( maskPix );
-
- SetGWorld( pictureGWorld, NULL);
- transparent = Color2Index( &gSWTransparentColor );
-
- START_32_BIT_MODE
-
- baseAddr = SWGetPixBaseAddr(pictPix);
- maskAddr = SWGetPixBaseAddr(maskPix);
- rowBytes = SWGetPixRowBytes(pictPix);
-
- baseAddr += rectP->top * rowBytes;
- baseAddr += (rectP->left * depth) >> 3;
- maskAddr += rectP->top * rowBytes;
- maskAddr += (rectP->left * depth) >> 3;
- rowBytes -= (width * depth) >> 3;
-
- // Copy from the image GWorld to the mask GWorld,
- // turning all non-white colors to black as we go.
- switch ( depth )
- {
- case 8:
- {
- UInt8 *dst = (UInt8 *) baseAddr;
- UInt8 *mask = (UInt8 *) maskAddr;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( *dst++ == transparent )
- *mask++ = kClear;
- else
- *mask++ = kSolid;
- }
- dst = (UInt8 *) ( (char *) dst + rowBytes );
- mask = (UInt8 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- case 16:
- {
- UInt16 *dst = (UInt16 *) baseAddr;
- UInt16 *mask = (UInt16 *) maskAddr;
-
- transparent &= kAlphaMask16;
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( (*dst++ & kAlphaMask16) == transparent )
- *mask++ = kClear;
- else
- *mask++ = kSolid;
- }
- dst = (UInt16 *) ( (char *) dst + rowBytes );
- mask = (UInt16 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- case 32:
- {
- UInt32 *dst = (UInt32 *) baseAddr;
- UInt32 *mask = (UInt32 *) maskAddr;
-
- transparent &= kAlphaMask32;
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( (*dst++ & kAlphaMask32) == transparent )
- *mask++ = kClear;
- else
- *mask++ = kSolid;
- }
- dst = (UInt32 *) ( (char *) dst + rowBytes );
- mask = (UInt32 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- default:
- err = paramErr;
- }
-
- END_32_BIT_MODE
-
- SetGWorld( saveGWorld, saveDevice);
-
- SetPixelsState( pictPix, pictPixelsState );
- SetPixelsState( maskPix, maskPixelsState );
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFixImageGWorld - erase non-masked parts of the image, so that 16-bit Sprites
- // can use the real 16-bit blitters, rather than the partial-mask versions.
- // Unmasked portions will be cleared for the masking blitter, others left as-is.
- // While this function doubles as a faster version of SWWhitenGWorld, it is only
- // called when loading Sprites in 16-bit or 32-bit that are not self-masking.
- //
- // Note1: the unmasked parts will be completely erased, so they can contain garbage
- // Note2: this function handles unlocked GWorlds (locks them temporarily)
- //
- // IMAGE <- MASK
- //
- // Update: this function now also fixes the alpha channel of the mask, for pixel collisions
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWFixImageGWorld( GWorldPtr pictureGWorld, GWorldPtr maskGWorld, RectPtr rectP )
- {
- GWorldPtr saveGWorld;
- GDHandle saveDevice;
- Ptr baseAddr;
- Ptr maskAddr;
- long rowBytes;
- long width,height;
- long depth;
- long x,y;
- unsigned short transparentValue;
- PixMapHandle pictPix;
- PixMapHandle maskPix;
- GWorldFlags pictPixelsState;
- GWorldFlags maskPixelsState;
- OSErr err = noErr;
-
- pictPix = GetGWorldPixMap( pictureGWorld );
- maskPix = GetGWorldPixMap( maskGWorld );
-
- SW_ASSERT( (**pictPix).pixelSize == (**maskPix).pixelSize );
-
- if ( rectP == NULL )
- rectP = &pictureGWorld->portRect;
-
- width = rectP->right - rectP->left;
- height = rectP->bottom - rectP->top;
-
- depth = (**pictPix).pixelSize;
- ComputePixelValues(depth);
- transparentValue = SWTransparentRGBValue;
-
- /* // afb: Removed this, since we might need to fix the MASK image
-
- // Determine whether we need to fix this GWorld's image at all?
- if (gSWTransparentColor.red == transparentValue &&
- gSWTransparentColor.green == transparentValue &&
- gSWTransparentColor.blue == transparentValue )
- {
- return noErr;
- }
- */
- // This function won't work in depths lower than 8-bit, so we
- // need to call the old SWWhitenGWorld in this case.
- if ( depth <= 8 )
- {
- SWWhitenGWorld(pictureGWorld);
- return noErr;
- }
-
- GetGWorld( &saveGWorld, &saveDevice);
-
- pictPixelsState = GetPixelsState( pictPix );
- LockPixels( pictPix );
- maskPixelsState = GetPixelsState( maskPix );
- LockPixels( maskPix );
-
- START_32_BIT_MODE
-
- baseAddr = SWGetPixBaseAddr(pictPix);
- maskAddr = SWGetPixBaseAddr(maskPix);
- rowBytes = SWGetPixRowBytes(pictPix);
-
- baseAddr += rectP->top * rowBytes;
- baseAddr += (rectP->left * depth) >> 3;
- maskAddr += rectP->top * rowBytes;
- maskAddr += (rectP->left * depth) >> 3;
- rowBytes -= (width * depth) >> 3;
-
- // Copy from the mask GWorld to the image GWorld,
- // but only clearing all the non-masked sections.
- switch ( depth )
- {
- case 8:
- {
- UInt8 *dst = (UInt8 *) baseAddr;
- UInt8 *mask = (UInt8 *) maskAddr;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( *mask )
- {
- *dst++ = 0;
- *mask++ = kClear;
- }
- else
- {
- dst++;
- *mask++ = kSolid;
- }
- }
- dst = (UInt8 *) ( (char *) dst + rowBytes );
- mask = (UInt8 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- case 16:
- {
- UInt16 *dst = (UInt16 *) baseAddr;
- UInt16 *mask = (UInt16 *) maskAddr;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( *mask )
- {
- *dst++ = 0;
- *mask++ = kClear;
- }
- else
- {
- dst++;
- *mask++ = kSolid;
- }
- }
- dst = (UInt16 *) ( (char *) dst + rowBytes );
- mask = (UInt16 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- case 32:
- {
- UInt32 *dst = (UInt32 *) baseAddr;
- UInt32 *mask = (UInt32 *) maskAddr;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( *mask )
- {
- *dst++ = 0;
- *mask++ = kClear;
- }
- else
- {
- dst++;
- *mask++ = kSolid;
- }
- }
- dst = (UInt32 *) ( (char *) dst + rowBytes );
- mask = (UInt32 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- default:
- err = paramErr;
- }
-
- END_32_BIT_MODE
-
- SetGWorld( saveGWorld, saveDevice);
-
- SetPixelsState( pictPix, pictPixelsState );
- SetPixelsState( maskPix, maskPixelsState );
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateMaskAndFixImage - this is equal to first calling SWCreateMask and then SWFixImage.
- // Calling this function is faster (up to twice) than calling them both separately.
- //
- // IMAGE -> MASK, MASK -> IMAGE
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateMaskAndFixImage( GWorldPtr pictureGWorld, GWorldPtr maskGWorld, RectPtr rectP )
- {
- UInt32 transparent;
- GWorldPtr saveGWorld;
- GDHandle saveDevice;
- Ptr baseAddr;
- Ptr maskAddr;
- long rowBytes;
- long width,height;
- long depth;
- long x,y;
- unsigned short transparentValue;
- PixMapHandle pictPix;
- PixMapHandle maskPix;
- GWorldFlags pictPixelsState;
- GWorldFlags maskPixelsState;
-
- pictPix = GetGWorldPixMap( pictureGWorld );
- maskPix = GetGWorldPixMap( maskGWorld );
-
- SW_ASSERT( (**pictPix).pixelSize == (**maskPix).pixelSize );
-
- if ( rectP == NULL )
- rectP = &pictureGWorld->portRect;
-
- width = rectP->right - rectP->left;
- height = rectP->bottom - rectP->top;
-
- depth = (**pictPix).pixelSize;
- ComputePixelValues(depth);
- transparentValue = SWTransparentRGBValue;
-
- // This function won't work in depths lower than 8-bit, so we
- // need to call the old SWBlackenGWorld in this case.
- if ( depth < 8 )
- {
- SWCopyGWorlds(pictureGWorld, maskGWorld);
- SWBlackenGWorld(maskGWorld);
- if (depth <= 8 )
- SWInvertGWorld(maskGWorld);
- SWWhitenGWorld(pictureGWorld);
-
- return noErr;
- }
-
- GetGWorld( &saveGWorld, &saveDevice);
-
- pictPixelsState = GetPixelsState( pictPix );
- LockPixels( pictPix );
- maskPixelsState = GetPixelsState( maskPix );
- LockPixels( maskPix );
-
- SetGWorld( pictureGWorld, (GDHandle) NULL);
- transparent = Color2Index( &gSWTransparentColor );
-
- START_32_BIT_MODE
-
- baseAddr = SWGetPixBaseAddr(pictPix);
- maskAddr = SWGetPixBaseAddr(maskPix);
- rowBytes = SWGetPixRowBytes(pictPix);
-
- baseAddr += rectP->top * rowBytes;
- baseAddr += (rectP->left * depth) >> 3;
- maskAddr += rectP->top * rowBytes;
- maskAddr += (rectP->left * depth) >> 3;
- rowBytes -= (width * depth) >> 3;
-
- switch ( depth )
- {
- case 8:
- {
- UInt8 *dst = (UInt8 *) baseAddr;
- UInt8 *mask = (UInt8 *) maskAddr;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( *dst == transparent )
- {
- *dst++ = 0;
- *mask++ = kClear;
- }
- else
- {
- dst++;
- *mask++ = kSolid;
- }
- }
- dst = (UInt8 *) ( (char *) dst + rowBytes );
- mask = (UInt8 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- case 16:
- {
- UInt16 *dst = (UInt16 *) baseAddr;
- UInt16 *mask = (UInt16 *) maskAddr;
-
- transparent &= kAlphaMask16;
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( (*dst & kAlphaMask16) == transparent )
- {
- *dst++ = 0;
- *mask++ = kClear;
- }
- else
- {
- dst++;
- *mask++ = kSolid;
- }
- }
- dst = (UInt16 *) ( (char *) dst + rowBytes );
- mask = (UInt16 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- case 32:
- {
- UInt32 *dst = (UInt32 *) baseAddr;
- UInt32 *mask = (UInt32 *) maskAddr;
-
- transparent &= kAlphaMask32;
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( (*dst & kAlphaMask32) == transparent )
- {
- *dst++ = 0;
- *mask++ = kClear;
- }
- else
- {
- dst++;
- *mask++ = kSolid;
- }
- }
- dst = (UInt32 *) ( (char *) dst + rowBytes );
- mask = (UInt32 *) ( (char *) mask + rowBytes );
- }
- }
- break;
- default:
- return paramErr;
- }
-
- END_32_BIT_MODE
-
- SetGWorld( saveGWorld, saveDevice);
-
- SetPixelsState( pictPix, pictPixelsState );
- SetPixelsState( maskPix, maskPixelsState );
-
- return noErr;
- }
-
-
- #pragma mark -
-
- // ColorSearchProc for SWBlackenGWorld
- static pascal Boolean blackenColorSearch( RGBColor *RGB, long *position );
-
- ///--------------------------------------------------------------------------------------
- // SWBlackenGWorld - converts all non-gSWTransparentColor pixels to black, all others
- // to white (transparent). Since this has been replaced with SWCreatePixelMaskFromGWorld,
- // this function is only called when the depth is lower than 8-bits.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWBlackenGWorld( GWorldPtr oldGWorld )
- {
- GWorldPtr saveGWorld, newGWld;
- GDHandle saveGDH;
- Rect gwldRect;
- GWorldFlags pixelState;
- ColorSearchUPP blackenColSearchUPP;
- PixMapHandle newPix;
- PixMapHandle oldPix;
- OSErr err;
-
- GetGWorld( &saveGWorld, &saveGDH );
-
- oldPix = GetGWorldPixMap(oldGWorld);
-
- gwldRect = oldGWorld->portRect;
- pixelState = GetPixelsState( oldPix );
-
- err = NewGWorld(&newGWld, 1, &gwldRect, nil, nil, 0 );
-
- if ( err == noErr )
- {
- // First, copy from the color GWorld to the 1-bit GWorld, turning all
- // non-white colors to black as we go.
- newPix = GetGWorldPixMap(newGWld);
- (void)LockPixels( newPix );
- (void)LockPixels( oldPix );
- SetGWorld( oldGWorld, nil );
- ForeColor(blackColor);
- BackColor(whiteColor);
- SetGWorld( newGWld, nil );
- blackenColSearchUPP = NewColorSearchProc( blackenColorSearch );
- AddSearch( blackenColSearchUPP );
- ComputePixelValues( (**oldPix).pixelSize );
- CopyBits (
- (BitMap*) *oldPix,
- (BitMap*) *newPix,
- &gwldRect,
- &gwldRect,
- srcCopy,
- nil);
- DelSearch( blackenColSearchUPP );
- DisposeRoutineDescriptor( blackenColSearchUPP );
-
- // Next, copy the result back into the original GWorld.
- SetGWorld( oldGWorld, nil );
- CopyBits (
- (BitMap*) *newPix,
- (BitMap*) *oldPix,
- &gwldRect,
- &gwldRect,
- srcCopy,
- nil);
-
- SetPixelsState( oldGWorld->portPixMap, pixelState );
- DisposeGWorld( newGWld );
- }
-
- SetGWorld( saveGWorld, saveGDH );
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
-
- ///--------------------------------------------------------------------------------------
- // blackenColorSearch
- ///--------------------------------------------------------------------------------------
-
- pascal Boolean blackenColorSearch( RGBColor *RGB, long* position )
- {
- #pragma unused(position)
-
- // Convert transparent pixels to "white", and the others to "black"
- if ( RGB->red == gSWTransparentColor.red &&
- RGB->green == gSWTransparentColor.green &&
- RGB->blue == gSWTransparentColor.blue )
- {
- RGB->red = RGB->green = RGB->blue = SWTransparentRGBValue; // transparent (white, 0)
- }
- else
- {
- RGB->red = RGB->green = RGB->blue = SWMaskedRGBValue; // masked (black, 1)
- }
-
- return ( false );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateRegionMaskFromGWorld - converts the image in pictureGWorld to a region mask
- //
- // useful for creating a region mask when there is no pixel mask
- // pictureGWorld does NOT have to be blackened before calling this function
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateRegionMaskFromGWorld( GWorldPtr pictureGWorld,
- Rect *pictureRect, RgnHandle maskRegion )
- {
- GWorldPtr saveGWorld, tempGWld;
- GDHandle saveGDH;
- GWorldFlags pixelState;
- ColorSearchUPP blackenColSearchUPP;
- PixMapHandle tempPix;
- PixMapHandle oldPix;
- OSErr err;
- Rect gwldRect;
-
- GetGWorld( &saveGWorld, &saveGDH );
-
- gwldRect = *pictureRect;
- OffsetRect(&gwldRect, -gwldRect.left, -gwldRect.top);
-
- err = NewGWorld(&tempGWld, 1, &gwldRect, nil, nil, 0 );
-
- if ( err == noErr )
- {
- oldPix = GetGWorldPixMap(pictureGWorld);
- pixelState = GetPixelsState( oldPix );
-
- // we want a mask compatible with BitMapToRegion (black is solid)
- ComputePixelValues( 8 );
-
- // First, copy from the color GWorld to the 1-bit GWorld,
- // turning everything to black and white as we go.
- tempPix = GetGWorldPixMap(tempGWld);
- (void)LockPixels( tempPix );
- (void)LockPixels( oldPix );
- SetGWorld( pictureGWorld, nil );
- ForeColor(blackColor);
- BackColor(whiteColor);
- SetGWorld( tempGWld, nil );
- ForeColor(blackColor);
- BackColor(whiteColor);
- blackenColSearchUPP = NewColorSearchProc( blackenColorSearch );
- AddSearch( blackenColSearchUPP );
- CopyBits (
- (BitMap*) *oldPix,
- (BitMap*) *tempPix,
- &gwldRect,
- &gwldRect,
- srcCopy,
- nil);
- DelSearch( blackenColSearchUPP );
- DisposeRoutineDescriptor( blackenColSearchUPP );
-
- // Then, update the region mask
- err = BitMapToRegion( maskRegion, (BitMap*) *tempPix);
-
- DisposeGWorld( tempGWld );
-
- SetPixelsState( pictureGWorld->portPixMap, pixelState );
- }
-
- SetGWorld( saveGWorld, saveGDH );
-
- SWSetStickyIfError( err );
- return err;
- }
-
- #pragma mark -
-
- // ColorSearchProc for SWWhitenGWorld
- static pascal Boolean whitenColorSearch( RGBColor *RGB, long *position );
-
- ///--------------------------------------------------------------------------------------
- // SWWhitenGWorld - changes all pixels in the GWorld matching gSWTransparentColor to white.
- // This function, along with SWSetTransparentColor, allows you to load self-masking sprites
- // without requiring the "transparent" color to be white. (With an additional delay,
- // that is.) Since this has been replace with SWFixImageGWorld, this is only used when
- // the depth is less than 8-bits.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWWhitenGWorld( GWorldPtr oldGWorld )
- {
- GWorldPtr saveGWorld, newGWld;
- GDHandle saveGDH;
- Rect gwldRect;
- GWorldFlags pixelState;
- ColorSearchUPP whitenColSearchUPP;
- OSErr err;
- PixMapHandle newPix;
- PixMapHandle oldPix;
-
- GetGWorld( &saveGWorld, &saveGDH );
-
- oldPix = GetGWorldPixMap(oldGWorld);
-
- GetGWorld( &saveGWorld, &saveGDH );
-
- gwldRect = oldGWorld->portRect;
- err = NewGWorld(&newGWld, (**oldPix).pixelSize, &gwldRect, nil, nil, 0 );
-
- if ( err == noErr )
- {
- newPix = GetGWorldPixMap(newGWld);
- pixelState = GetPixelsState( oldPix );
- (void)LockPixels( newPix );
- (void)LockPixels( GetGWorldPixMap(oldGWorld) );
- SetGWorld( oldGWorld, nil );
- ForeColor(blackColor);
- BackColor(whiteColor);
- SetGWorld( newGWld, nil );
- whitenColSearchUPP = NewColorSearchProc( whitenColorSearch );
- AddSearch( whitenColSearchUPP );
- ComputePixelValues( (**oldPix).pixelSize );
- CopyBits (
- (BitMap*) *oldPix,
- (BitMap*) *newPix,
- &gwldRect,
- &gwldRect,
- srcCopy,
- nil);
- DelSearch( whitenColSearchUPP );
- DisposeRoutineDescriptor( whitenColSearchUPP );
-
- SetGWorld( oldGWorld, nil );
- CopyBits (
- (BitMap*) *newPix,
- (BitMap*) *oldPix,
- &gwldRect,
- &gwldRect,
- srcCopy,
- nil);
-
- SetPixelsState( oldPix, pixelState );
- DisposeGWorld( newGWld );
- }
-
- SetGWorld( saveGWorld, saveGDH );
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // whitenColorSearch
- ///--------------------------------------------------------------------------------------
-
- pascal Boolean whitenColorSearch( RGBColor *RGB, long* position )
- {
- #pragma unused(position)
-
- // Convert transparent pixels to 0, leaving others untouched
- if ( RGB->red == gSWTransparentColor.red &&
- RGB->green == gSWTransparentColor.green &&
- RGB->blue == gSWTransparentColor.blue )
- {
- RGB->red = RGB->green = RGB->blue = SWTransparentRGBValue; // set to zero
- }
-
- return false;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFastWhitenGWorld - same as SWWhitenGWorld, but faster, although this only works
- // in depths of 8 bits and above. Currently only called by SWUpdateSpriteFromPictResource.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWFastWhitenGWorld( GWorldPtr pictureGWorld )
- {
- UInt32 transparent;
- GWorldPtr saveGWorld;
- GDHandle saveDevice;
- Ptr baseAddr;
- long rowBytes;
- long width, height;
- long depth, bytes;
- long x, y;
- unsigned short transparentValue;
- PixMapHandle pictPix;
- GWorldFlags pictPixelsState;
-
- pictPix = GetGWorldPixMap( pictureGWorld );
-
- width = pictureGWorld->portRect.right - pictureGWorld->portRect.left;
- height = pictureGWorld->portRect.bottom - pictureGWorld->portRect.top;
-
- depth = (**pictPix).pixelSize;
- ComputePixelValues(depth);
- transparentValue = SWTransparentRGBValue;
-
- // Exit if the depth is lower than 8 bits.
- if ( depth < 8 )
- return kWrongDepthErr;
-
- GetGWorld( &saveGWorld, &saveDevice);
-
- pictPixelsState = GetPixelsState( pictPix );
- LockPixels( pictPix );
-
- SetGWorld( pictureGWorld, (GDHandle) NULL);
- transparent = Color2Index( &gSWTransparentColor );
-
- START_32_BIT_MODE
-
- baseAddr = SWGetPixBaseAddr(pictPix);
- rowBytes = SWGetPixRowBytes(pictPix);
-
- bytes = (width * depth) >> 3;
- rowBytes -= bytes;
-
- switch ( depth )
- {
- case 8:
- {
- UInt8 *dst = (UInt8 *) baseAddr;
-
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( *dst == transparent )
- *dst++ = 0;
- else
- dst++;
- }
- dst = (UInt8 *) ( (char *) dst + rowBytes );
- }
- }
- break;
- case 16:
- {
- UInt16 *dst = (UInt16 *) baseAddr;
-
- transparent &= kAlphaMask16;
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( (*dst & kAlphaMask16) == transparent )
- *dst++ = 0;
- else
- dst++;
- }
- dst = (UInt16 *) ( (char *) dst + rowBytes );
- }
- }
- break;
- case 32:
- {
- UInt32 *dst = (UInt32 *) baseAddr;
-
- transparent &= kAlphaMask32;
- for ( y = 0; y < height; y++ )
- {
- for ( x = 0; x < width; x++ )
- {
- if ( (*dst & kAlphaMask32) == transparent )
- *dst++ = 0;
- else
- dst++;
- }
- dst = (UInt32 *) ( (char *) dst + rowBytes );
- }
- }
- break;
- default:
- return paramErr;
- }
-
- END_32_BIT_MODE
-
- SetGWorld( saveGWorld, saveDevice);
-
- SetPixelsState( pictPix, pictPixelsState );
-
- return noErr;
- }
-
- #pragma mark -
-
- ///--------------------------------------------------------------------------------------
- // SWClearStickyError
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWClearStickyError(void)
- {
- gSWStickyError = noErr;
- }
-
- ///--------------------------------------------------------------------------------------
- // SWStickyError
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWStickyError(void)
- {
- return gSWStickyError;
- }
-
- ///--------------------------------------------------------------------------------------
- // SWSetStickyIfError
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetStickyIfError(OSErr errNum)
- {
- if ( errNum != noErr )
- gSWStickyError = errNum;
- }
-
- #pragma mark -
-
- ///--------------------------------------------------------------------------------------
- // SWHasSystem7
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWHasSystem7(void)
- {
- long versionNumber;
- OSErr err;
-
- err = Gestalt( gestaltSystemVersion, &versionNumber );
-
- SWSetStickyIfError( err );
- return (err == noErr) && (versionNumber >= 0x0700);
- }
-
- #if (SW_ASSERT_ON == 1)
- ///--------------------------------------------------------------------------------------
- // SWAssertFail - called when the expression in SW_ASSERT() is false.
- ///--------------------------------------------------------------------------------------
-
- void SWAssertFail(char* filename, int lineNum)
- {
- Str255 fileString = "\p";
- Str15 lineString;
- short n, result;
- unsigned long junkTime;
-
- NumToString((long)lineNum, lineString);
-
- for (n = 0; filename[n] != 0; n++)
- {
- fileString[n+1] = filename[n];
- }
- fileString[0] += n;
-
- // Call the CleanUpCallBack if there is one.
- if (gSWCleanUpCallBackP != NULL)
- (*gSWCleanUpCallBackP)();
-
- InitCursor();
- ParamText("\pAssertion failure! This program will now quit. The failure occurred here:",
- fileString, lineString, "\pN/A");
- result = StopAlert(kAssertAlertID, NULL);
-
- // Make it beep if the dialog box couldn't be displayed for some reason.
- if (result < 0)
- {
- SysBeep(1);
- Delay(15, &junkTime); // Wait for beep to finish
- }
-
- // If a CleanUpSpriteWorld is installed, turn its VBL Syncing off.
- if (gSWCleanUpSpriteWorldP != NULL)
- SWSyncSpriteWorldToVBL(gSWCleanUpSpriteWorldP, false);
-
- ExitToShell();
- }
- #endif
-
-